home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / EDITGRID.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.6 KB  |  315 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1997. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. /* editgrid demonstrates how a simple 2nd order grid mesh or a more
  9.    complex 4th order grid mesh can rendered with OpenGL evaluators.
  10.    The control points for either grid can be interactively moved in 2D
  11.    by selecting and moving with the left mouse button.  Antialising can
  12.    also be enabled from the pop-up menu. */
  13.  
  14. /* Compile: cc -o editgrid editgrid.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */
  15.  
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <GL/glut.h>
  19.  
  20. int antialiasing = 0;
  21. int gridSize = 20;
  22. GLuint selectedPoint = (GLuint) ~0;
  23. int winWidth, winHeight;
  24. GLuint selectBuffer[64];
  25. GLdouble modelMatrix[16], projMatrix[16];
  26. GLint viewport[4];
  27.  
  28. /* Simple 2nd order initial grid.  4 points (2 by 2). */
  29. GLfloat grid2x2[2][2][3] =
  30. {
  31.   {
  32.     {-2.0, -2.0, 0.0},
  33.     {2.0, -2.0, 0.0}},
  34.   {
  35.     {-2.0, 2.0, 0.0},
  36.     {2.0, 2.0, 0.0}}
  37. };
  38.  
  39. /* More complex 4nd order initial grid.  16 points (4 by 4). */
  40. GLfloat grid4x4[4][4][3] =
  41. {
  42.   {
  43.     {-2.0, -2.0, 0.0},
  44.     {-0.5, -2.0, 0.0},
  45.     {0.5, -2.0, 0.0},
  46.     {2.0, -2.0, 0.0}},
  47.   {
  48.     {-2.0, -0.5, 0.0},
  49.     {-0.5, -0.5, 0.0},
  50.     {0.5, -0.5, 0.0},
  51.     {2.0, -0.5, 0.0}},
  52.   {
  53.     {-2.0, 0.5, 0.0},
  54.     {-0.5, 0.5, 0.0},
  55.     {0.5, 0.5, 0.0},
  56.     {2.0, 0.5, 0.0}},
  57.   {
  58.     {-2.0, 2.0, 0.0},
  59.     {-0.5, 2.0, 0.0},
  60.     {0.5, 2.0, 0.0},
  61.     {2.0, 2.0, 0.0}}
  62. };
  63. GLfloat *grid = &grid4x4[0][0][0];
  64. int uSize = 4;
  65. int vSize = 4;
  66.  
  67. void
  68. setupMesh(void)
  69. {
  70.   glEnable(GL_MAP2_VERTEX_3);
  71.   glMapGrid2f(gridSize, 0.0, 1.0, gridSize, 0.0, 1.0);
  72. }
  73.  
  74. void
  75. evaluateGrid(void)
  76. {
  77.   glColor3f(1.0, 1.0, 1.0);
  78.   glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, uSize, 0, 1, uSize * 3, vSize, grid);
  79.   glEvalMesh2(GL_LINE, 0, gridSize, 0, gridSize);
  80. }
  81.  
  82. void
  83. drawControlPoints(void)
  84. {
  85.   int i;
  86.  
  87.   glColor3f(1.0, 1.0, 0.0);
  88.   glPointSize(5.0);
  89.   glBegin(GL_POINTS);
  90.   for (i = 0; i < uSize * vSize; i++) {
  91.     glVertex3fv(&grid[i * 3]);
  92.   }
  93.   glEnd();
  94. }
  95.  
  96. void
  97. selectControlPoints(void)
  98. {
  99.   int i;
  100.  
  101.   for (i = 0; i < uSize * vSize; i++) {
  102.     glLoadName(i);
  103.     glBegin(GL_POINTS);
  104.     glVertex3fv(&grid[i * 3]);
  105.     glEnd();
  106.   }
  107. }
  108.  
  109. void
  110. display(void)
  111. {
  112.   glClear(GL_COLOR_BUFFER_BIT);
  113.   evaluateGrid();
  114.   drawControlPoints();
  115.   glutSwapBuffers();
  116. }
  117.  
  118. void
  119. ortho(void)
  120. {
  121.   if (winWidth <= winHeight)
  122.     glOrtho(-4.0, 4.0, -4.0 * (GLfloat) winHeight / (GLfloat) winWidth,
  123.       4.0 * (GLfloat) winHeight / (GLfloat) winWidth, -4.0, 4.0);
  124.   else
  125.     glOrtho(-4.0 * (GLfloat) winWidth / (GLfloat) winHeight,
  126.       4.0 * (GLfloat) winWidth / (GLfloat) winHeight, -4.0, 4.0, -4.0, 4.0);
  127. }
  128.  
  129. GLuint
  130. pick(int x, int y)
  131. {
  132.   int hits;
  133.  
  134.   (void) glRenderMode(GL_SELECT);
  135.   glInitNames();
  136.   glPushName(~0);
  137.   glMatrixMode(GL_PROJECTION);
  138.   glPushMatrix();
  139.   glLoadIdentity();
  140.   gluPickMatrix(x, winHeight - y, 8.0, 8.0, viewport);
  141.   ortho();
  142.   glMatrixMode(GL_MODELVIEW);
  143.   selectControlPoints();
  144.   glMatrixMode(GL_PROJECTION);
  145.   glPopMatrix();
  146.   glMatrixMode(GL_MODELVIEW);
  147.   hits = glRenderMode(GL_RENDER);
  148.   if (hits) {
  149. #ifdef DEBUG
  150.     {
  151.       unsigned int i;
  152.       GLint names;
  153.       GLuint *ptr;
  154.  
  155.       printf("hits = %d\n", hits);
  156.       ptr = (GLuint *) selectBuffer;
  157.       for (i = 0; i < hits; i++) {  /* for each hit  */
  158.         int j;
  159.  
  160.         names = *ptr;
  161.         printf("number of names for hit = %d\n", *ptr);
  162.         ptr++;
  163.         printf("  z1 is %g;", (float) *ptr / 0xffffffff);
  164.         ptr++;
  165.         printf("  z2 is %g\n", (float) *ptr / 0xffffffff);
  166.         ptr++;
  167.         printf(" the name is ");
  168.         for (j = 0; j < names; j++) {  /* For each name. */
  169.           printf("%d ", *ptr);
  170.           ptr++;
  171.         }
  172.         printf("\n");
  173.       }
  174.     }
  175. #endif
  176.     return selectBuffer[3];
  177.   } else {
  178.     return ~0;
  179.   }
  180. }
  181.  
  182. void
  183. reshape(int w, int h)
  184. {
  185.   glViewport(0, 0, w, h);
  186.   winWidth = w;
  187.   winHeight = h;
  188.  
  189.   glMatrixMode(GL_PROJECTION);
  190.   glLoadIdentity();
  191.   ortho();
  192.   glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
  193.   glMatrixMode(GL_MODELVIEW);
  194.   glLoadIdentity();
  195.   glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
  196.   viewport[0] = 0;
  197.   viewport[1] = 0;
  198.   viewport[2] = winWidth;
  199.   viewport[3] = winHeight;
  200. }
  201.  
  202. void
  203. mouse(int button, int state, int x, int y)
  204. {
  205.   if (button == GLUT_LEFT_BUTTON) {
  206.     if (state == GLUT_DOWN) {
  207.       selectedPoint = pick(x, y);
  208.     } else {
  209.       selectedPoint = -1;
  210.     }
  211.   }
  212. }
  213.  
  214. void
  215. motion(int x, int y)
  216. {
  217.   GLdouble objx, objy, objz;
  218.  
  219.   if (selectedPoint != ~0) {
  220.     gluUnProject(x, winHeight - y, 0.95,
  221.       modelMatrix, projMatrix, viewport,
  222.       &objx, &objy, &objz);
  223.     grid[selectedPoint * 3 + 0] = objx;
  224.     grid[selectedPoint * 3 + 1] = objy;
  225.     glutPostRedisplay();
  226.   }
  227. }
  228.  
  229. /* ARGSUSED1 */
  230. static void
  231. keyboard(unsigned char key, int x, int y)
  232. {
  233.   switch (key) {
  234.   case 27:
  235.     exit(0);
  236.   }
  237. }
  238.  
  239. enum {
  240.   M_2ND_ORDER_GRID, M_4TH_ORDER_GRID, M_INCREASE_GRID, M_DECREASE_GRID, M_TOGGLE_ANTIALIASING, M_QUIT
  241. };
  242.  
  243. void
  244. menu(int value)
  245. {
  246.   switch (value) {
  247.   case M_2ND_ORDER_GRID:
  248.     grid = &grid2x2[0][0][0];
  249.     uSize = 2;
  250.     vSize = 2;
  251.     setupMesh();
  252.     break;
  253.   case M_4TH_ORDER_GRID:
  254.     grid = &grid4x4[0][0][0];
  255.     uSize = 4;
  256.     vSize = 4;
  257.     setupMesh();
  258.     break;
  259.   case M_INCREASE_GRID:
  260.     gridSize += 2;
  261.     setupMesh();
  262.     break;
  263.   case M_DECREASE_GRID:
  264.     gridSize -= 2;
  265.     if (gridSize < 2) {
  266.       gridSize = 2;
  267.     }
  268.     setupMesh();
  269.     break;
  270.   case M_TOGGLE_ANTIALIASING:
  271.     if (antialiasing) {
  272.       antialiasing = 0;
  273.       glDisable(GL_BLEND);
  274.       glDisable(GL_LINE_SMOOTH);
  275.       glDisable(GL_POINT_SMOOTH);
  276.     } else {
  277.       antialiasing = 1;
  278.       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  279.       glEnable(GL_BLEND);
  280.       glEnable(GL_LINE_SMOOTH);
  281.       glEnable(GL_POINT_SMOOTH);
  282.     }
  283.     break;
  284.   case M_QUIT:
  285.     exit(0);
  286.     break;
  287.   }
  288.   glutPostRedisplay();
  289. }
  290.  
  291. int
  292. main(int argc, char **argv)
  293. {
  294.   glutInit(&argc, argv);
  295.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  296.   glutCreateWindow("editgrid");
  297.   glutReshapeFunc(reshape);
  298.   glutDisplayFunc(display);
  299.   glutMouseFunc(mouse);
  300.   glutKeyboardFunc(keyboard);
  301.   glutMotionFunc(motion);
  302.   glutCreateMenu(menu);
  303.   glutAddMenuEntry("2nd order grid", M_2ND_ORDER_GRID);
  304.   glutAddMenuEntry("4nd order grid", M_4TH_ORDER_GRID);
  305.   glutAddMenuEntry("Increase grid sizing by 2", M_INCREASE_GRID);
  306.   glutAddMenuEntry("Decrease grid sizing by 2", M_DECREASE_GRID);
  307.   glutAddMenuEntry("Toggle antialiasing", M_TOGGLE_ANTIALIASING);
  308.   glutAddMenuEntry("Quit", M_QUIT);
  309.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  310.   glSelectBuffer(sizeof(selectBuffer), selectBuffer);
  311.   setupMesh();
  312.   glutMainLoop();
  313.   return 0;             /* ANSI C requires main to return int. */
  314. }
  315.